/**
 * 300. 最长上升子序列
 * https://leetcode-cn.com/problems/longest-increasing-subsequence/
 * 进阶：二分查找 + 贪心法
 */
public class Solutions_300 {
    public static void main(String[] args) {
        int[] nums = {10, 9, 2, 5, 3, 7, 101, 18};  // output: 4  {2, 3, 7, 101}
//        int[] nums = {4, 10, 4, 3, 8, 9};  // output: 3  {3, 8, 9}
//        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};
//         output: 6  {10, 22, 33, 50, 60, 80}

        int result = lengthOfLIS(nums);
        System.out.println(result);
    }

    public static int lengthOfLIS(int[] nums) {
        if (nums == null || nums.length < 1) {
            // 判空
            return 0;
        }
        int res = 1;
        int len = nums.length;

        if (len == 1) {
            // 直接返回 1 的情况
            return res;
        }
        // dp数组，dp[2] = 3：表示在索引为 2 的元素上，能够形成的最长上升子序列的长度是 3
        int[] dp = new int[len];
        // 默认为 1，元素自己本身就是一个长度为 1 的子序列
        dp[0] = 1;

        for (int i = 1; i < len; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            // 当前遍历索引 i 处，能够组成的最长上升子序列的元素个数
            // 若该元素比之前的元素都小，那么元素自己本身就是一个长度为 1 的子序列
            dp[i] = Math.max(1, dp[i]);
            // 记录结果：最长上升子序列的长度/元素个数
            res = Math.max(res, dp[i]);
        }
        return res;
    }
}
